package social.p2pnative;

import com.srcgeneratora.utils.FileGeneratorUtil;
import java.util.ArrayList;
import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import social.p2pnative.model.AdvertisementClass;
import social.p2pnative.model.AdvertisementField;

/**
 *
 * @author cadmilo
 */
@SupportedAnnotationTypes("social.p2pnative.Advertisement")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class AdvertismentProcessor extends AbstractProcessor {

    private static boolean proccesed = false;
    private FileGeneratorUtil fgu;

    @Override
    public synchronized void init(ProcessingEnvironment pe) {
        super.init(pe);
        fgu = new FileGeneratorUtil(processingEnv, "social/p2pnative/templates/");
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment re) {
        if (!proccesed) {
            ArrayList<AdvertisementClass> advs = new ArrayList<AdvertisementClass>();
            for (Element e : re.getElementsAnnotatedWith(Advertisement.class)) {
                Advertisement adv = e.getAnnotation(Advertisement.class);
                final TypeElement clazz = (TypeElement) e;
                ArrayList<AdvertisementField> aFields = new ArrayList<AdvertisementField>();
                String type = (adv.type().isEmpty() ? clazz.getSimpleName().toString() : adv.type());
                if (e.getKind() != ElementKind.CLASS) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Not a class", e);
                    continue;
                }
                for (Element el : e.getEnclosedElements()) {
                    if (el.getKind() == ElementKind.FIELD && el.getAnnotation(Field.class) != null) {
                        AdvertisementField afield = new AdvertisementField(el.getSimpleName().toString(), el.getAnnotation(Indexed.class) != null);
                        aFields.add(afield);
                        System.out.println(el.getSimpleName());
                    }
                }
                AdvertisementClass aclass = new AdvertisementClass(clazz.getQualifiedName().toString(), clazz.getSimpleName().toString(), adv.mimeType(), type, aFields);
                Context context = new VelocityContext();
                context.put("adv", aclass);
                fgu.createFile(aclass.getQualifiedName() + "Impl", "AdvertisementImpl.vm", context);
                advs.add(aclass);
            }
            Context context = new VelocityContext();
            context.put("advs", advs);
            fgu.createFile("social.p2pnative.AdvertisementFactoryGenImpl", "AdvertisementFactoryGenImpl.vm", context);
            proccesed = true;
        }
        return true;
    }
}
